package top.xtcoder.jdcbase.base.config;

import javax.sql.DataSource;

import org.beetl.core.GroupTemplate;
import org.beetl.sql.core.ClasspathLoader;
import org.beetl.sql.core.ConnectionSource;
import org.beetl.sql.core.ConnectionSourceHelper;
import org.beetl.sql.core.Interceptor;
import org.beetl.sql.core.SQLLoader;
import org.beetl.sql.core.SQLManager;
import org.beetl.sql.core.UnderlinedNameConversion;
import org.beetl.sql.core.db.DBStyle;
import org.beetl.sql.core.db.MySqlStyle;
import org.beetl.sql.ext.DebugInterceptor;
import org.noear.wood.Command;
import org.noear.wood.DbContext;
import org.noear.wood.WoodConfig;
import org.noear.wood.ext.Fun1;
import org.nutz.dao.Dao;
import org.nutz.dao.impl.NutDao;
import org.nutz.dao.util.Daos;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;

import com.alibaba.druid.pool.DruidDataSource;
import com.ejlchina.searcher.dialect.Dialect;
import com.ejlchina.searcher.dialect.PostgreSqlDialect;

import top.xtcoder.jdcbase.base.common.btsql.BlankFun;
import top.xtcoder.jdcbase.base.common.btsql.Vo2PgsqlFieldFun;

@Configuration
@PropertySource(value = "classpath:druid.properties")
public class DruidConfig {
	private Logger logger = LoggerFactory.getLogger(DruidConfig.class);
	
	@Autowired
	private NutzdaoConfig config;
	
	@Value("${wood.debug:false}")
	private boolean woodDebug;

	@Bean(destroyMethod = "close", initMethod = "init")
    @ConfigurationProperties(prefix = "spring.datasource")
    public DataSource druidDataSource() {
        return new DruidDataSource();
    }

	/**
	 * 配置Nutz Dao操作数据库 
	 * @param druidDataSource
	 * @return
	 */
	@Bean
	public Dao dao(DataSource druidDataSource) {
		Dao dao = new NutDao(druidDataSource);
		if(!config.isAutoCreate()) {
			return dao;
		}
		if(config.isPbEnable()) {
			System.out.println("扫描实体【top.xtcoder.jdcbase】，自动建表");
			Daos.createTablesInPackage(dao, "top.xtcoder.jdcbase", false);
		}

		String[] entityPackages = config.getEntityPackage();

		if(entityPackages != null && entityPackages.length > 0) {
			for(String ep : entityPackages) {
				System.out.println("扫描实体【" + ep + "】，自动建表");
//					logger.debug("扫描实体【" + ep + "】，自动建表");
				Daos.createTablesInPackage(dao, ep, false);
			}
		}

		return dao;
	}

	@Bean
	public DbContext woodDB(DataSource druidDataSource) {
		DbContext woodDb = new DbContext(druidDataSource);
		
		if(woodDebug) {
			WoodConfig.onExecuteAft((cmd) -> {
				System.out.println("[Wood.After]" + cmd.text);
				System.out.println("[Wood.After]" + cmd.paramMap());
			});
			
			WoodConfig.onExecuteBef((cmd) -> {
				System.out.println("[Wood.Before]" + cmd.text);
				System.out.println("[Wood.Before]" + cmd.paramMap());
				return true;
			});
		}
		
		return woodDb;
	}
	
	@Bean
	public Dialect myDialect() {
		// bean
	    return new PostgreSqlDialect();
	}
	
	@Bean
	public SQLManager sqlManager(DataSource druidDataSource) {
		DBStyle mysql = new MySqlStyle();
		// sql语句放在classpagth的/sql 目录下
		SQLLoader loader = new ClasspathLoader("/sqls");
		// 数据库命名跟java命名一样，所以采用DefaultNameConversion，还有一个是UnderlinedNameConversion，下划线风格的
		UnderlinedNameConversion nc = new  UnderlinedNameConversion();
		// 最后，创建一个SQLManager,DebugInterceptor 不是必须的，但可以通过它查看sql执行情况
		ConnectionSource source = ConnectionSourceHelper.getSingle(druidDataSource);
		SQLManager sqlManager = new SQLManager(mysql
				,loader
				,source
				,nc
				,new Interceptor[]{new DebugInterceptor()});
		GroupTemplate gt = sqlManager.getBeetl().getGroupTemplate();
		gt.registerFunction("vo2PgsqlField", new Vo2PgsqlFieldFun());
		gt.registerFunction("isBlank", new BlankFun());
		return sqlManager;
	}
}
